#include <stdint.h>

#include "A51Cuda.h"
#include "A51CudaKernel.h"

#define MEMORY_ALIGNMENT 4096
#define ALIGN_UP(x, size) (((size_t)x + (size - 1)) & (~(size - 1)))

#define DATA_SIZE 4096
#define BLOCK_SIZE 32

#define CHAINSTATE_RUNNING  0
#define CHAINSTATE_FINISHED 1


class A51Cuda;

class A51CudaSlice {
    private:
        enum eState {
            ePopulate,
            eKernel,
            eProcess
        };

        eState state;
        uint64_t finishedMask;
        unsigned int maxCycles;
        unsigned int maxRound;
        unsigned int nCycles;
        bool isRunning;

        A51Cuda::JobPiece_s* jobs;

        uint64_t* hm_states;
        uint64_t* d_states;
        uint64_t* hm_roundfuncs;
        uint64_t* d_roundfuncs;
        unsigned int* hm_finished;
        unsigned int* d_finished;

        void populate();
        void invokeKernel();
        void process();

        A51Cuda* controller;

    public:
        A51CudaSlice(A51Cuda* controller, int deviceId, int dp, unsigned int maxRound);
        ~A51CudaSlice();
        int getTotalSlots();
        void tick();
};
